package hc.j2me.util;

import hc.core.L;
import hc.core.util.LogManager;
import hc.j2me.Main;
import hc.j2me.Starter;

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

public class ImageUtility {

	public static final int BLACK_RGB_VALUE = 0x00FFFFFF;//-16777216;
	public static final int FULL_TRANS = 0x00FFFFFF;
	public final static int upSideColor = 0xad8e63;
	public final static int downSideColor = 0x291819;
	
	public static final boolean isHardAlpha = (Display.getDisplay(Main.main).numAlphaLevels() == 256);

	/**
	 * 转大，缩小均可
	 * @param imge
	 * @param newWidth
	 * @param newHeight
	 * @return
	 */
	public static Image scaleImage(Image imge, int newWidth, int newHeight) {
		final int width = imge.getWidth();
		final int height = imge.getHeight();

		int rgb[] = new int[width * height];

		imge.getRGB(rgb, 0, width, 0, 0, width, height);

		int scale[] = new int[newWidth * newHeight];
		for (int yy = 0; yy < newHeight; yy++) {
			int dy = yy * height / newHeight;
			for (int xx = 0; xx < newWidth; xx++) {
				int dx = xx * width / newWidth;
				scale[(newWidth * yy) + xx] = rgb[(width * dy) + dx];
			}
		}

		return Image.createRGBImage(scale, newWidth, newHeight, true);
	}
	
	private static final short borderSize = 1;
	public static final Font UI_Font = loadMiniFont();
		//Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_PLAIN, Font.SIZE_SMALL);//FACE_SYSTEM
	public static final int FontHeight = UI_Font.getHeight() + borderSize * 2;
	public static final int COLOR_TRANS_LAY = 0xcc847139;
	public static final int COLOR_TRANS_LAY_FROM_GETRGB = getColorFromRGB();
	public static final int LOW_RGB = 0xFFFFFF;
	public static final int LIGHT_SELECT_AREA = 0x55000000 | (COLOR_TRANS_LAY_FROM_GETRGB & LOW_RGB);
	
	private static int getColorFromRGB() {
		Image image = Image.createImage(1, 1);
		Graphics g = image.getGraphics();
		g.setColor(COLOR_TRANS_LAY);
		g.drawLine(0, 0, 1, 0);
		int[] d = new int[1];
		image.getRGB(d, 0, 1, 0, 0, 1, 1);
		final int out = d[0] & 0xFFFFFFFF;
//		L.V = L.O ? false : LogManager.log("COLOR_TRANS_LAY : " + (COLOR_TRANS_LAY & 0xffffff) + ", get : " + (out & 0xffffff));
		return out;
	}
	
	private static Font loadMiniFont(){
		int[] faces = {Font.FACE_MONOSPACE, Font.FACE_PROPORTIONAL, 
				Font.FACE_SYSTEM};
		int index = -1, height = 20000;
		for (int j = 0; j < faces.length; j++) {
			Font ft = Font.getFont(faces[j], Font.STYLE_PLAIN, Font.SIZE_SMALL);
			if(ft != null && ft.getHeight() < height){
				index = j;
				height = ft.getHeight();
			}
		}
		if(index == -1){
			return Font.getDefaultFont();
		}else{
			return Font.getFont(faces[index], Font.STYLE_PLAIN, Font.SIZE_SMALL);
		}
	}

	public static final short BLUE = 1, RED = 2, WHITE = 3, BLACK = 4, GRAY = 5, YELLOW = 6, GREEN = 7;
	
	public static int getColor(short color){
		if(color == BLUE){
			return ((89 & 0xFF) << 16) | ((89 & 0xFF) << 8) | (255 & 0xFF);
		}else if(color == WHITE){
			return ((255 & 0xFF) << 16) | ((255 & 0xFF) << 8) | (255 & 0xFF);
		}else if(color == BLACK){
			return 0;
		}else if(color == GRAY){
			return ((192 & 0xFF) << 16) | ((192 & 0xFF) << 8) | (192 & 0xFF);
		}else if(color == YELLOW){
			return ((255 & 0xFF) << 16) | ((255 & 0xFF) << 8) | (0 & 0xFF);
		}else if(color == GREEN){
			return ((102 & 0xFF) << 16) | ((255 & 0xFF) << 8) | (0 & 0xFF);
		}
		return 0;
	}
	public static void setColor(Graphics g, short color){
		if(color == BLUE){
			g.setColor(89,89,255);
		}else if(color == WHITE){
			g.setColor(255, 255, 255);
		}else if(color == BLACK){
			g.setColor(0, 0, 0);
		}else if(color == GRAY){
			g.setColor(192,192,192);
		}else if(color == YELLOW){
			g.setColor(255,255,0);
		}else if(color == GREEN){
			g.setColor(102,255,0);
		}
	}

	/**
	 * 将黑色部分转为指定通道色
	 * @param image
	 * @param alpha
	 * @param useHardAlpha TODO
	 * @return immutable Image
	 */
	public static Image tranBlackToTransfor(Image image, boolean useHardAlpha) {
		final int noAlpha = (COLOR_TRANS_LAY_FROM_GETRGB & LOW_RGB);
		final int width = image.getWidth();
		final int height = image.getHeight();
		final int[] array = new int[width * height];
		image.getRGB(array, 0, width, 0, 0, width, height);
		
		for (int i = 0; i < array.length; i++) {
			if((array[i] & LOW_RGB) == noAlpha){
				//为黑色
				array[i] = COLOR_TRANS_LAY;// 这里为改变ALPHA数值。FF为不透明。00为全透明。
			}
		}
		if(useHardAlpha){
			return createSafeAlphaImg(array, width, height, array.length, useHardAlpha);
		}else{
			return createSafeAlphaImg(array, width, height, array.length, isAlphaEnable());
		}
	}

	public static boolean isAlphaEnable() {
		return Starter.config.isUseAlpha && isHardAlpha;
	}

	/**
	 * 
	 * @param array
	 * @param width
	 * @param height
	 * @param size
	 * @param tryUseAlpha
	 * @return immutable Image
	 */
	public static Image createSafeAlphaImg(final int[] array, final int width, final int height, 
			final int size, final boolean tryUseAlpha) {
		if(tryUseAlpha){
			try{
				if(size <= Starter.config.passAlphaMin){
					return Image.createRGBImage(array, width, height, tryUseAlpha);
				}else if(size < Starter.config.failAlphaMax){
					int oldFail = Starter.config.failAlphaMax;
					Starter.config.failAlphaMax = size;
					Starter.update(Starter.config);
					
		//			L.V = L.O ? false : LogManager.log("failAlphaMax:" + size);
					
					Image out = Image.createRGBImage(array, width, height, tryUseAlpha);
					
					Starter.config.failAlphaMax = oldFail;
					Starter.config.passAlphaMin = size;
					Starter.update(Starter.config);
					
		//			L.V = L.O ? false : LogManager.log("alpha pass Min:" + size);
					
					return out;
				}
			}catch (Throwable e) {
			}
		}
		return Image.createRGBImage(array, width, height, false);
	}
	
	public static int sp_bound = 5;

	public static void fillBox(final int x1, final int y1, final int x2, final int y2, final int color,
			final int width, final int[] array) {
		for (int i = y1; i <= y2; i++) {
			ImageUtility.drawLine(x1, i, x2, i, color, array, width, false);
		}
	}
	
	public static void drawImage(final int[] imgData, 
			final int rectx, final int recty, final int rectwidth, final int rectheight, 
			final int imgWidth, final int imgHeight,
			final boolean isAlpha,
			final int arrayX, final int arrayY,
			final int arrayWidth, final int[] array) {
		
		final int double256 = 256 * 256;

		for (int stepY = 0; stepY < rectheight; stepY++) {
			for (int stepX = 0, 
					rowX = (recty + stepY) * imgWidth + rectx, 
					rowTox = (arrayY + stepY) * arrayWidth + arrayX; 
					stepX < rectwidth; stepX++) {
				final int pixelUp = imgData[rowX++];
				final int pixelBottomIdx = rowTox++;
				if(isAlpha == false){
					array[pixelBottomIdx] = pixelUp;
				}else{
					final int alphaUp = (pixelUp >> 24) & 0xFF;
					if(alphaUp == 0xFF){
						array[pixelBottomIdx] = pixelUp;
					}else{
						if(alphaUp == 0){
							continue;
						}
						
						final int pixelBottom = array[pixelBottomIdx];
						final int alphaBottom = (pixelBottom >> 24) & 0xFF;
						
						final int rUp = (pixelUp >> 16) & 0xFF;
						final int rDown = (pixelBottom >> 16) & 0xFF;
						final int rNew = (rUp * alphaUp * 256 + rDown * alphaBottom * (256 - alphaUp)) / double256;
						
						final int gUp = (pixelUp >> 8) & 0xFF;
						final int gDown = (pixelBottom >> 8) & 0xFF;
						final int gNew = (gUp * alphaUp * 256 + gDown * alphaBottom * (256 - alphaUp)) / double256;

						final int bUp = pixelUp & 0xFF;
						final int bDown = pixelBottom & 0xFF;
						final int bNew = (bUp * alphaUp * 256 + bDown * alphaBottom * (256 - alphaUp)) / double256;

						final int alphaNew =  (double256 - (256 - alphaUp) * (256 - alphaBottom)) / 256;
//						L.V = L.O ? false : LogManager.log("r : " + rNew + ", g : " + gNew + ", b : " + bNew + 
//								", alpha UP : " + alphaUp + ", alpha bottom : " + alphaBottom + ", alpha : " + alphaNew);
						array[pixelBottomIdx] = (alphaNew << 24) | (rNew << 16) | (gNew << 8) | bNew;
					}
				}
			}
		}
	}

	public static void drawBox(final int x1, final int y1, final int x2, final int y2, final int upSide,
				final int downSide, final int width, final int[] array) {
	//		L.V = L.O ? false : LogManager.log("draw width:" + width + " x : " + x1 + ", y : " + y1 + ", x2 : " + x2 + ", y2 : " + y2);
			
			//顶
			ImageUtility.drawLine(x1, y1, x2 + 1, y1, upSide, array, width, true);
			//左
			ImageUtility.drawLine(x1, y1, x1, y2, upSide, array, width, true);
			//右
			ImageUtility.drawLine(x2, y1, x2, y2, downSide, array, width, true);
			//底
			ImageUtility.drawLine(x1, y2, x2 + 1, y2, downSide, array, width, true);
		}

	public static void drawLine(final int x, final int y, final int toX, final int toY, final int color, 
				final int[] imageData, final int width, final boolean isKeepOldAlpha){
	//		L.V = L.O ? false : LogManager.log("draw line, x:" + x + ", y : " + y + ", x2 : " + toX + ", y2 : " + toY);
			if(x == toX){
				//竖线
	//			L.V = L.O ? false : LogManager.log("Draw shuxian");
				final int height = (toY - y);
				for (int i = 0; i <= height; i++) {
					final int idx = (y + i) * width + x;
					if(isKeepOldAlpha){
						final int oldColor = imageData[idx];
						imageData[idx] = (oldColor & 0xFF000000) | (color & 0xFFFFFFFF);
					}else{
						imageData[idx] = color;
					}
				}
			}else if(y == toY){
				//横线
	//			L.V = L.O ? false : LogManager.log("Draw henxian");
				final int startIdx = y * width;
				for (int i = x; i < toX; i++) {
					final int idx = startIdx + i;
					if(isKeepOldAlpha){
						final int oldColor = imageData[idx];
						imageData[idx] = (oldColor & 0xFF000000) | (color & 0xFFFFFFFF);
					}else{
						imageData[idx] = color;
					}
	//				L.V = L.O ? false : LogManager.log("pixel idx:" + idx + ", old Color:" + oldColor + ", new Color:" + imageData[idx]);
				}
			}
		}

	public static void drawBoxAtCell(int areaWidth, int[] array, int cellX, int cellY, int blockWidth, int splitWidth, int icoSize, int upColor, int downColor) {
			final int x1 = cellX * blockWidth + splitWidth - 1;
			final int y1 = cellY * blockWidth + splitWidth - 1;
	//				L.V = L.O ? false : LogManager.log("draw box x1:" + x1 + ", y1:" + y1);
			drawBox(x1, y1, x1 + icoSize + 1, y1 + icoSize + 1, upColor, downColor, areaWidth, array);
		}

	public static void initBoxAtCell(int width, int height, int alpha, int[] array, int _blockWidth, int userMouseSplitWidth, int _16) {
		for (int i = 0; i < array.length; i++) {
			array[i] = alpha;// 这里为改变ALPHA数值。FF为不透明。00为全透明。
		}
		final boolean isWidthMucher = width > height;
		int count = isWidthMucher?(width / height):(height / width);
		for (int i = 0; i < count; i++) {
			drawBoxAtCell(width, array, isWidthMucher?i:0, isWidthMucher?0:i, _blockWidth, userMouseSplitWidth, _16, upSideColor, downSideColor);
		}
	}


}
